#include "catalogo.h"
#include <iostream>
#include <sstream>
#include <string>
#include <cassert>
#include <cstdlib>

using namespace std;

void asegurar(const Catalogo& c, string s) {
	ostringstream out;
	c.mostrarCatalogo(out);
	string t = out.str();
	if (s != t) {
		cerr << s << " != " << t << endl;
		assert(false);
	}
}

template<class T>
void asegurar(const Conjunto<T>& l, string s) {
	ostringstream out;
	l.mostrarConjunto(out);
	string t = out.str();
	if (s != t) {
		cerr << s << " != " << t << endl;
		assert(false);
	}
}

void asegurar(const Multiconj_materiales& l, string s) {
	ostringstream out;
	l.mostrarMulticonj_materiales(out);
	string t = out.str();
	if (s != t) {
		cerr << s << " != " << t << endl;
		assert(false);
	}
}

#define RUNTEST(t) { cerr << "Corriendo test " << #t << endl; t (); cerr << "Terminado test " << #t << endl; }

void TestViviendas(){
	Catalogo c;
	asegurar(c.viviendas(), "[]");
	Multiconj_materiales mm;
	c.agregarVivienda(mm);
	assert(1==c.cantidadViviendas());
	assert(c.viviendas().pertenecen(c.cantidadViviendas()-1));
	assert(c.cantidadViviendas()==c.viviendas().cardinal());
	mm.agregar(2,4);
	c.agregarVivienda(mm);
	assert(c.materiales(0).vacio());
	assert(2==c.cantidadViviendas());
	assert(c.viviendas().pertenecen(c.cantidadViviendas()-1));
	assert(c.cantidadViviendas()==c.viviendas().cardinal());
	mm.agregar(5,6);
	c.agregarVivienda(mm);
	c.agregarVivienda(mm);
	c.agregarVivienda(mm);
	assert(5==c.cantidadViviendas());
	assert(c.viviendas().pertenecen(c.cantidadViviendas()-1));
	assert(c.cantidadViviendas()==c.viviendas().cardinal());
	int i=0;
	Conjunto<vivienda> conj;
	while(i<c.cantidadViviendas()){
		conj.agregar(i);
		i++;
	}
	assert(conj==c.viviendas());
}

void TestMateriales(){
	Catalogo c;
	Multiconj_materiales mm;
	c.agregarVivienda(mm);
	//asegurar(c, "[<0,[]>]");
	assert(c.materiales(0)==mm);
	Multiconj_materiales ms;
	ms.agregar(9,6);
	c.agregarVivienda(ms);
	Multiconj_materiales m;
	m.agregar(5,4);
	m.agregar(3,2);
	m.agregar(4,3);
	c.agregarVivienda(m);
	assert(c.materiales(0)==mm);
	assert(c.materiales(1)==ms);
	assert(c.materiales(2)==m);
	assert(9==c.cantMateriales());
	//asegurar(c, "[<0,[]>,<1,[<9;6>]>,<2,[<5;4>,<3;2>,<4;3>]>]");
}

void testIterMateriales(){
	Catalogo c;
	Multiconj_materiales mm;
	mm.agregar(1,6);
	mm.agregar(3,7);
	mm.agregar(5,36);
	c.agregarVivienda(mm);
	Multiconj_materiales::IterMateriales it_m = c.crearIterMateriales(0);
	Multiconj_materiales ms;
	while(it_m.tieneProximo()){
		material mat = it_m.avanzar();
		nat cant = mm.cardinal(mat);
		ms.agregar(mat, cant);
	}
	assert(mm==ms);
}

main(){
	RUNTEST (TestViviendas); 
	RUNTEST (TestMateriales);
	RUNTEST (testIterMateriales);
   return 0;
}
